#include <string>
#include "UdpServer.hpp"



//客户端使用的时候也是
// ./UDP_CLIENT  server_port server_ip（因为服务器和客户端是同一家公司写的！）
int main(int argc, char* argv[]){
    if(argc != 3) {
        std::cerr << "please usage : " << "./UDP_SERVER port ip" << std::endl;
        return 1;
    }

    //1.创建socket
    int socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(socket_fd < 0){
        std::cerr << "client : socket create error" << std::endl;
    } 

    //现在有一个问题：
    //就是客户端需要bind嘛？ 需要
    //但是，不需要手动显式bind ，操作系统会自动bind(在该进程向服务器发送的时候，操作系统自动bind)

    //但是，为什么不需要呢？
    //因为客户端会存在很多的进程，如果指定bind一个，很容易起冲突！

    //现在，需要先向服务器发消息，然后再来接收信息 -> 首先得知道要往哪里发送
    //服务器的端口号和ip是知道的，是主机序列
    uint16_t server_port = std::stoi(std::string(argv[1]));
    std::string server_ip = argv[2];
    
    //转为网络序列
    server_port = htons(server_port);

    
    struct sockaddr_in peer;
    peer.sin_family = AF_INET;
    peer.sin_port = server_port;
    peer.sin_addr.s_addr = inet_addr(server_ip.c_str());

    while(1){
        //1.向远端服务器发送信息
        std::string send_msg;
        std::cout << "please input message : " ;
        fflush(stdout);
        std::getline(std::cin, send_msg);
        
        int n = sendto(socket_fd, send_msg.c_str(), send_msg.size(), 0, (struct sockaddr*)&peer, sizeof(peer));
        (void)n;

        struct sockaddr_in get_peer; //还是需要获取一下发送信息来的服务器的ip和端口号
        socklen_t len = sizeof(get_peer);
        //因为有可能一台机器和多态服务器通信，所以需要接收！

        char recv_msg[1024] = {0};
        int m = recvfrom(socket_fd, recv_msg, sizeof(recv_msg) - 1, 0, (struct sockaddr*)&get_peer, &len);
        std::cout << recv_msg << std::endl;
        (void)m;
    }


    return 0;
}